home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 21
/
Cream of the Crop 21 (Terry Blount) (October 1996).iso
/
program
/
gnudev1.zip
/
emx
/
doc
/
duel.man
< prev
next >
Wrap
Text File
|
1993-03-19
|
28KB
|
502 lines
DDDDuuuueeeellll((((1111)))) VVVVeeeerrrrssssiiiioooonnnn 1111....11110000 ((((MMMMaaaarrrr 99993333)))) DDDDuuuueeeellll((((1111))))
NNNNAAAAMMMMEEEE
duel - A high level C debugging language extension to gdb
SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
dddduuuueeeellll [gdb options] [_p_r_o_g[_c_o_r_e|_p_r_o_c_I_D]]
DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
Duel is a special purpose language designed for concise state
exploration of debugged C programs, currently implemented under the
GNU debugger _g_d_b(1). Duel is invoked by entering the shell command
_d_u_e_l instead of _g_d_b. It is identical to gdb except for comments, which
begin with `##' instead of `#', and the new _d_l command for Duel
expressions:
_g_d_b> dl x[1..10] >? 5
x[3] = 14
x[8] = 6
prints the array elements x[1] to x[10] that are greater than 5. The
output includes the values 14 and 6, as well as their symbolic
representation "x[3]" and "x[8]".
IIIIFFFF YYYYOOOOUUUU NNNNEEEEVVVVEEEERRRR UUUUSSSSEEEEDDDD GGGGDDDDBBBB
The improved functionality added by Duel merits a fresh look even by
debugger shunners. Gdb is a powerful debugger with many commands, a
thick manual and various interfaces including _e_m_a_c_s(1) and _x_x_g_d_b(1).
These gdb commands should help you get started:
_b _l_i_n_e set a breakpoint at the line (b func to break at a function)
_d _n delete breakpoint number n (gdb prints n when bp occurs)
_l _l_i_n_e list the source beginning at line (l file.c:line for module)
_r _p_a_r_m run/restart the program with the given parameters
_s single-step to the next statement (steps into function calls)
_n single-step to the next line, skipping over function calls
_c continue execution
_b_t show a stack trace
_p _e_x_p evaluate a symbolic expression
_d_l _e_x_p evaluate a Duel expression
_d_l _g_d_b give a gdb command summary
The most common use is `b func' followed by `r' followed by several
`n' and `s', evaluating expressions in between.
DDDDUUUUEEEELLLL QQQQUUUUIIIICCCCKKKK SSSSTTTTAAAARRRRTTTT
Duel is implemented by adding the _d_l command to gdb. All gdb commands
work as before. The dl command, however, is interpreted by duel. Gdb
concepts (such as the value history) do not work in the dl command,
and duel concepts are not understood by other gdb command.
Duel is based on expressions which return multiple values. The x..y
operator returns the integers from x to y; the x,y operator returns x
and then y, e.g.
_g_d_b> dl (1,9,12..15,22)
prints 1, 9, 12, 13, 14, 15 and 22. Such expressions can be used
wherever a single value is used, e.g.
_g_d_b> dl x[0..99]=0 ;
assigns zero to the first 100 elements of array x. The semantics of
x[i] are the same as in C. They are applied for each of the values
returned by 0..99, which can be thought of as an implied external
loop. The trailing semicolon indicates evaluation for side-effects
only, with no output. Duel incorporates C operators, casts C
statements as expressions, and supports limited variable declaration:
_g_d_b> dl int i;for(i=0;i<100;i++)
if(x[i]<0) printf("x[%d]=%d\n",i,x[i]);
x[7] = -4
The semicolon prevents Duel output; only output from printf is
printed. Aliases are defined with x:=y and provide an alternative to
variable declaration. We could also return x[i] instead of using
printf:
_g_d_b> dl if(x[i:=0..99]<0) x[i]
x[i] = -4
The symbolic output "x[i]" can be fixed by surrounding i with {}, i.e.
_g_d_b> dl if(x[i:=0..99]<0) x[{i}]
x[7] = -4
The {} are like (), but force the symbolic evaluation to use i's
value, instead of "i". You can usually avoid this altogether with
direct Duel operators:
_g_d_b> dl x[..100] <? 0
x[7] = -4
The ..n operator is a shorthand for 0..n-1, i.e. ..100 is the same as
0..99. The x<?y, x==?y, x>=?y, etc., operators compare their left
side operand to their right side operand as in C, but return the left
side value if the comparison result is true. Otherwise, they look for
the next values to compare, without returning anything.
Duel's x.y and x->y allow an expression y, evaluated under x's scope:
_g_d_b> dl emp[..100].(if(code>400) (code,name))
emp[46].code = 682
emp[46].name = "Ela"
The if() expression is evaluated under the scope of each element of
emp[], an array of structures. In C terms, we had to write:
_g_d_b> dl int i; for(i=0; i<100 ; i++)
if(emp[i].code>400) emp[{i}].code,emp[{i}].name
A useful alternative to loops is the x=>y operator. It returns y for
each value of x, setting `_' to reference x's value, e.g.
_g_d_b> ..100 => if(emp[_].code>400) emp[_].code,emp[_].name
Using `_' instead of `i' also avoids the need for {i}. Finally, the
x-->y operator expands lists and other data structures. If head points
to a linked list threaded through the next field, then:
_g_d_b> dl head-->next->data
head->data = 12
head->next->data = 14
head-->next[[2]]->data = 20
head-->next[[3]]->data = 26
produce the data field for each node in the list. x-->y returns x, x-
>y, x->y->y, x->y->y->y, ... until a NULL is found. The symbolic
output "x-->y[[n]]" indicates that ->y was applied n times. x[[y]] is
also the selection operator:
_g_d_b> dl head-->next[[50..60]]->data
return the 50th through the 60th elements in the list. The #/x
operator counts the number of values, so
_g_d_b> dl #/( head-->next->data >? 50 )
counts the number of data elements over 50 on the list. Several other
operators, including x@y, x#y and active call stack access are
described in the operators section.
OOOOPPPPEEEERRRRAAAATTTTOOOORRRRSSSS SSSSUUUUMMMMMMMMAAAARRRRYYYY
Assoc Operators Details
left {} () [] -> . f() --> x-->y expands x->y x->y->y ...
x[[y]] x#y x@y generate x; select, index or stop-at y
right #/ - * & ! ~ ++ -- (cast) #/x number of x values
frame(n) sizeof(x) reference to call stack level n
left x/y x*y x%y multiply, divide, reminder
left x-y x+y add, subtract
left x<<y x>>y shift left/right
none x..y ..y x.. ..y = 0..y-1. x..y return x, x+1...y
left < > <= >= <? >? <=? >=? x>?y return x if x>y
left == != ==? !=? x==?y return x if x==y
left x&y bit-and
left x^y bit-xor
left x|y bit-or
left x&&y &&/x &&/x are all x values non-zero?
left x||y ||/x ||/x is any x value non-zero?
right x? y:z foreach x, if(x) y else z
right x:=y x=y x+=y ... x:=y set x as an alias to y
left x,y return x, then y
right x=>y foreach x, evaluate y with x value `_'